#ifndef LOGO_LEX
#define LOGO_LEX
#include "Basic/String.h"
#include "Collections/List.h"
#include "Collections/Dictionary.h"
#include "Collections/Linq.h"
#include "Basic/Pointer.h"
#include "Regex/Regex.h"

namespace logo
{
	using namespace zl;
	using namespace zl::collections;
	using namespace zl::regex;

	enum class tokentype
	{
		UNKNOW = -1,
		SEP = 0,
		NUMERICAL,
		ADD,
		SUB,
		MUL,
		DIV,
		GE,
		LE,
		GT,
		LT,
		EQ,
		OPENBRACKETS,
		CLOSEBRACKETS,
		OPENMIDBRACKETS,
		CLOSEMIDBRACKETS,
		VAR,
		KEYWORD,
		CMD,
		DEF
	};

	class Token
	{
	public:
		zint                      row;
		zint                      col;
		std::wstring              value;
		tokentype                 type = tokentype::UNKNOW;
	};

	class  LexError
	{
	public:
		Token                     token;
		std::wstring              message;
	};

	class  CodeLine
	{
	public:
		List<Token>               tokens;
		CodeLine();
		~CodeLine();
		CodeLine(CodeLine& rhs);
		CodeLine& operator= (const CodeLine& rhs);
	};

	class  CodeFile
	{
	public:
		List<CodeLine>            lines;
	public:
		CodeFile();
		~CodeFile();
		static  Ptr<CodeFile>     Parse(const std::wstring& input, List<LexError>& errors);
	};
};
#endif